package fr.lelouet.ga.reducers;

import java.util.HashSet;
import java.util.Set;

import fr.lelouet.ga.Reducer;

/**
 * reduces a set by selecting couples of elements, and select the worst one to
 * be reduced.
 * 
 * @author le louet
 * 
 * @param <T>
 *            type the algorithm uses.
 */
public class TurnamentReducer<T> implements Reducer<T> {

    protected int maxSize;
    protected Competitor<T> competitor;

    /**
     * 
     * @param maxSize
     *            the size goal of the set that are reduced
     * @param competitor
     *            the way to comptete two elements
     */
    public TurnamentReducer(int maxSize, Competitor<T> competitor) {
	this.maxSize = maxSize;
	this.competitor = competitor;
    }

    @Override
    public Set<T> toReduce(Set<T> set) {
	Set<T> ret = new HashSet<T>();
	while (set.size() - ret.size() > maxSize) {
	    int aimToRemove = set.size() - ret.size() - maxSize;
	    T challenger = null;
	    for (T iter : set) {
		if (!ret.contains(iter)) {
		    if (challenger != null) {
			ret.add(competitor.loser(challenger, iter));
			aimToRemove--;
			challenger = null;
		    } else {
			challenger = iter;
		    }
		}
		if (aimToRemove == 0) {
		    return ret;
		}
	    }
	}

	return ret;
    }

}
